#include "../../src/ipc/IpcIoClient.h"
#include "../../src/ipc/IpcIoSocket.h"
#include "../../src/log/LogFactory.h"
#include "../../src/tools/ShareApi.h"
#include "../test_type.h"
#include <map>

using namespace LibTools;
using namespace std;

DWORD DealConnect(CSockError ec, void* invoker);
DWORD DealCWrite(char* data, DWORD dwSize, CSockError ec, void* invoker);
DWORD DealCRead(char* data, DWORD dwSize, CSockError ec, void* invoker);

static bool g_run = true;
static SharedPtr<CIpcIoClient> g_service = new CIpcIoClient;
static int g_int = 0;
static map<SOCKIDEN, string> g_strs;

#ifdef TEST_IPC_CLIENT
int main(int argc, char* argv[])
{
#ifdef WIN32
	LibTools::ShareApi::PrintDumpInfo(true);
#else
	LibTools::ShareApi::PrintDumpInfo();
#endif
	CSockError ec;
	LOG_SET_LEVEL(LibTools::LOG_NORMAL);
	LOG_SET_WRITE_CONSOLE(true);
	ec = g_service->Init("TEST_IPC_SERVER");
	CHECKERROR(ec, "init failed!");
	CIpcIoSocket cliIPC[3];
	for (size_t i = 0; i < 3; i++)
	{
#ifdef WIN32
		cliIPC[i].SetAddr("TEST_IPC_SERVER");
		cliIPC[i].WaitNamedPipe(30 * 1000);
#endif
		cliIPC[i].SetService(g_service->GetIpcServicePtr());
		g_strs[cliIPC[i].GetSocketID()] = "";
		cliIPC[i].AsyncConnect(&DealConnect, &(cliIPC[i]));
	}


	while (g_run) g_service->Run_One();
	g_service->WaitServerStop();

	return 0;
}
#endif // TEST_IPC_CLIENT

DWORD DealConnect(CSockError ec, void* invoker)
{
	CIpcIoSocket* ipc = (CIpcIoSocket*)invoker;
	LOG_TOOLS(LOG_NORMAL) << "connect succ?" << (bool)(ec.GetError() == CSockError::SUCC) << ", client id:" << ipc->GetSocketID();
	if (ec) 
	{
		LOG_TOOLS(LOG_NORMAL) << "connect failed!" << ec.GetErrorMsg();
		g_run = false;
	}
	else
	{
		LOG_TOOLS(LOG_NORMAL) << "connect succ!";
		g_strs[ipc->GetSocketID()] = format("send count = %d, client id = %lld", ++g_int, ipc->GetSocketID());
		//g_service->AsyncSend(*ipc, CStreamIteator(g_str.begin(), g_str.end()), &DealCWrite, ipc);
		ipc->AsyncSend(CStreamIteator((char*)g_strs[ipc->GetSocketID()].data(), 
			(char*)g_strs[ipc->GetSocketID()].data() + g_strs[ipc->GetSocketID()].size()), &DealCWrite, ipc);
	}

	return ec.GetSysError();
}

DWORD DealCWrite(char* data, DWORD dwSize, CSockError ec, void* invoker)
{
	CIpcIoSocket* ipc = (CIpcIoSocket*)invoker;
	LOG_TOOLS(LOG_NORMAL) << "send succ?" << (bool)(ec.GetError() == CSockError::SUCC) << ", client id:" << ipc->GetSocketID();
	if (ec)
	{
		LOG_TOOLS(LOG_NORMAL) << "DealCWrite failed!" << ec.GetErrorMsg();
		g_run = false;
	}
	else
	{
		LOG_TOOLS(LOG_NORMAL) << "DealCWrite succ!" << dwSize;
		g_strs[ipc->GetSocketID()].resize(1024);
		//g_service->AsyncRead(*ipc, CStreamIteator(g_str.begin(), g_str.end()), &DealCRead, ipc);
		ipc->AsyncRead(CStreamIteator((char*)g_strs[ipc->GetSocketID()].data(), 
			(char*)g_strs[ipc->GetSocketID()].data() + g_strs[ipc->GetSocketID()].size()), &DealCRead, ipc);
	}

	return ec.GetSysError();
}

DWORD DealCRead(char* data, DWORD dwSize, CSockError ec, void* invoker)
{
	CIpcIoSocket* ipc = (CIpcIoSocket*)invoker;
	LOG_TOOLS(LOG_NORMAL) << "read succ?" << (bool)(ec.GetError() == CSockError::SUCC) << ", client id:" << ipc->GetSocketID();
	if (ec)
	{
		LOG_TOOLS(LOG_NORMAL) << "DealCRead failed!" << ec.GetErrorMsg();
		g_run = false;
	}
	else
	{
		g_strs[ipc->GetSocketID()].erase(dwSize);
		LOG_TOOLS(LOG_NORMAL) << "DealCRead succ!" << "size:" << dwSize << ",msg:" << g_strs[ipc->GetSocketID()];
		ShareApi::Sleep(3000);
		g_strs[ipc->GetSocketID()] = format("send count = %d, client id = %lld", ++g_int, ipc->GetSocketID());
		//g_service->AsyncSend(*ipc, CStreamIteator(g_str.begin(), g_str.end()), &DealCWrite, ipc);
		ipc->AsyncSend(CStreamIteator((char*)g_strs[ipc->GetSocketID()].data(), 
			(char*)g_strs[ipc->GetSocketID()].data() + g_strs[ipc->GetSocketID()].size()), &DealCWrite, ipc);
	}

	return ec.GetSysError();
}
